; 主引导程序
;
; LOADER_BASE_ADDR equ 0xA000
; LOADER_START_SECTOR equ 0x2
; --------------------------------------------------------------------
%include "boot.inc"

SECTION MBR vstart=0x7c00
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov fs, ax
    mov sp, 0x7c00
    mov ax, 0xb800
    mov gs, ax

;清屏
;利用0x60号功能，上卷全部行，则可清屏
;INT 0X10 功能号: 0x06 功能描述:上卷窗口
; AH 功能号=0x06
; AL = 上卷的行数（如果为0，表示全部）
; BH = 上卷行属性
; (CL, CH) = 窗口左上角位置(x,y)
; (DL, DH) = 窗口右下角位置(x,y)
    mov ax, 0600h
    mov bx, 0700h
    mov cx, 0
    mov dx, 184fh
    int 10h

    mov byte [gs:0x00], '1'
    mov byte [gs:0x01], 0xa4

    mov byte [gs:0x02], ' '
    mov byte [gs:0x03], 0xa4

    mov byte [gs:0x04], 'M'
    mov byte [gs:0x05], 0xa4

    mov byte [gs:0x06], 'B'
    mov byte [gs:0x07], 0xa4

    mov byte [gs:0x08], 'R'
    mov byte [gs:0x09], 0xa4

    mov eax, LOADER_START_SECTOR
    mov bx, LOADER_BASE_ADDR
    mov cx, 1
    call rd_disk_m_16

    jmp LOADER_BASE_ADDR


;----------------------------------------------------------------
;功能：读取硬盘n个扇区
rd_disk_m_16:
;----------------------------------------------------------------
    mov esi, eax
    mov di,  cx

;第一步：设置需读取的扇区数
    mov dx,  0x1f2
    mov al,  cl   
    out dx,  al

    ;;;;;;;;;;;;;;;;;;
    mov eax, esi

;第二步: 将LBA地址存入0x1f3-0x1f6
    mov dx,  0x1f3
    out dx,  al

    mov cl, 8
    shr eax, cl
    mov dx, 0x1f4
    out dx, al

    shr eax, cl
    mov dx, 0x1f5
    out dx, al

    shr eax, cl
    and al, 0x0f
    or al, 0xe0
    mov dx, 0x1f6
    out dx, al

;第三步：向0x1f7端口写入读命令,0x20
    mov dx, 0x1f7
    mov al, 0x20
    out dx, al


;第四步:检测硬盘状态
.not_ready:
    nop
    in al, dx
    and al, 0x88

    cmp al, 0x08
    jnz  .not_ready

;第五步:从0x1f0端口读取数据
    mov ax, di
    mov dx,  256
    mul dx
    mov cx, ax
    mov dx, 0x1f0
.go_on_read:
    in ax, dx
    mov [bx], ax
    add bx, 2
    loop  .go_on_read
    ret


times 510-($-$$) db 0
db 0x55,0xaa